package com.bjsdzk.collector.otherFlatform;

import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;
import java.util.concurrent.ConcurrentHashMap;

import javax.annotation.PostConstruct;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.json.*;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Component;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSON;
import com.aliyun.openservices.iot.api.Profile;
import com.aliyun.openservices.iot.api.message.MessageClientFactory;
import com.aliyun.openservices.iot.api.message.api.MessageClient;
import com.aliyun.openservices.iot.api.message.callback.MessageCallback;
import com.aliyun.openservices.iot.api.message.entity.Message;
import com.aliyun.openservices.iot.api.message.entity.MessageToken;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.iot.model.v20180120.*;
import com.aliyuncs.profile.DefaultProfile;
import com.bjsdzk.backend.rpc.before.AliIotBefore;
import com.bjsdzk.collector.entity.RealTimeData;

@Component
@org.springframework.context.annotation.Profile("pro")
public class AliIotRK {
	private static Logger logger = LoggerFactory.getLogger(AliIotRK.class);
	@Autowired
	private MongoTemplate mongoTemplate;
    @Reference( check = false,version ="1.0.0",lazy=true,loadbalance="allLoadBalance")
    private AliIotBefore aliIotBefore;

	// regionId
	private static String regionId = "cn-shanghai";
	// 阿里云uid
	private static String uid = "1101556420115550";
	private static String accessKeyId = "LTAIs3hIEkwRKJMW";
	private static String accessSecret = "M6DUkJP3wetnZPoF8hKm5GBWAHFBF4";
	public static Map<String,String> productKey =new ConcurrentHashMap<>();
	public static IAcsClient client;
	static {
		DefaultProfile profile = DefaultProfile.getProfile("cn-shanghai", accessKeyId, accessSecret);
		client = new DefaultAcsClient(profile);
		productKey.put("rk", "a1Dj4aHpqnC");
		productKey.put("ss130", "a1sCmu63UR6");
	}

	@PostConstruct
	public void getData() {
		// endPoint: https://${uid}.iot-as-http2.${region}.aliyuncs.com
		String endPoint = "https://" + uid + ".iot-as-http2." + regionId + ".aliyuncs.com";

		// 连接配置
		Profile profile = Profile.getAccessKeyProfile(endPoint, regionId, accessKeyId, accessSecret);

		// 构造客户端
		MessageClient client = MessageClientFactory.messageClient(profile);

//        client.setMessageListener("/${"+YourProductKey+"}/#",messageCallback);
		// 数据接收

		rkData(client);

		client.connect(messageToken -> {
			Message m = messageToken.getMessage();
			logger.info("iot receive  message from " + m);
			return MessageCallback.Action.CommitSuccess;
		});
		logger.info("ali iot connect :"+client.isConnected());
	}

	public void rkData(MessageClient client){
		String pk=productKey.get("rk");

		client.setMessageListener("/as/mqtt/status/"+pk+"/+", (messageToken) -> {
			Message m = messageToken.getMessage();
			String message = new String(m.getPayload());
			logger.info("ali iot status:"+message);
			aliIotBefore.changeState(message);
			return MessageCallback.Action.CommitSuccess;
		});

		client.setMessageListener("/"+pk+"/+/user/update", (messageToken) ->{
			Message m = messageToken.getMessage();
			String data=new String(m.getPayload());
			logger.info("ali iot rk update: " + m);
			JSONObject json;
			JSONObject currentData;
			try {
				json = new JSONObject(data);
				String cmd = json.getString("cmd");
				String id = json.getString("id");
				switch (cmd) {
					case "value": {
						currentData=json.getJSONObject("data");
						JSONArray signal = currentData.getJSONArray("signal");
						JSONArray voltage = currentData.getJSONArray("voltage");
						JSONArray current = currentData.getJSONArray("current");
						JSONArray leakage = currentData.getJSONArray("leakage");
						JSONArray activepower = currentData.getJSONArray("activepower");
						JSONArray temperature = currentData.getJSONArray("temperature");
						JSONArray factor = currentData.getJSONArray("factor");
						JSONArray meterage = currentData.getJSONArray("meterage");
						List<RealTimeData> list =new ArrayList<>();
						Calendar calendar = Calendar.getInstance();
						calendar.add(Calendar.HOUR_OF_DAY,8);
						Date date=calendar.getTime();
						addList(list, "信号强度",388,"",signal.getDouble(0),date,id);
						addList(list, "联网次数",3888,"",signal.getDouble(1),date,id);



						addList(list, "A相电压",9,"V",voltage.getDouble(0),date,id);
						addList(list, "B相电压",10,"V",voltage.getDouble(1),date,id);
						addList(list, "C相电压",11,"V",voltage.getDouble(2),date,id);

						addList(list, "A相电流",12,"A",current.getDouble(0),date,id);
						addList(list, "B相电流",13,"A",current.getDouble(1),date,id);
						addList(list, "C相电流",14,"A",current.getDouble(2),date,id);

						addList(list, "剩余电流",63,"mA",leakage.getDouble(0),date,id);

						addList(list, "第一路温度",5,"℃",temperature.getDouble(0),date,id);
						addList(list, "第二路温度",6,"℃",temperature.getDouble(1),date,id);
						addList(list, "第三路温度",7,"℃",temperature.getDouble(2),date,id);
						addList(list, "第四路温度",8,"℃",temperature.getDouble(3),date,id);

						double avalue = new BigDecimal(activepower.getDouble(0)/1000).setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue();
						double bvalue = new BigDecimal(activepower.getDouble(1)/1000).setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue();
						double cvalue = new BigDecimal(activepower.getDouble(2)/1000).setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue();
						double totalActivepower = new BigDecimal(avalue).add(new BigDecimal(bvalue)).add(new BigDecimal(cvalue)).setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue();
						addList(list, "A相有功功率",16,"kW",avalue,date,id);
						addList(list, "B相有功功率",17,"kW",bvalue,date,id);
						addList(list, "C相有功功率",18,"kW",cvalue,date,id);
						addList(list, "总有功功率",19,"kW",totalActivepower,date,id);

						double factorValue0 = new BigDecimal(factor.getDouble(0)/100).setScale(3,BigDecimal.ROUND_HALF_UP).doubleValue();
						double factorValue1 = new BigDecimal(factor.getDouble(1)/100).setScale(3,BigDecimal.ROUND_HALF_UP).doubleValue();
						double factorValue2 = new BigDecimal(factor.getDouble(2)/100).setScale(3,BigDecimal.ROUND_HALF_UP).doubleValue();

						addList(list, "A相功率因数",20,"",factorValue0,date,id);
						addList(list, "B相功率因数",21,"",factorValue1,date,id);
						addList(list, "C相功率因数",22,"",factorValue2,date,id);

						double azvalue = new BigDecimal(meterage.getDouble(0)/1000).setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue();
						double bzvalue = new BigDecimal(meterage.getDouble(1)/1000).setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue();
						double czvalue = new BigDecimal(meterage.getDouble(2)/1000).setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue();
						addList(list, "A相正向有功电能",1,"kWh",azvalue,date,id);
						addList(list, "B相正向有功电能",2,"kWh",bzvalue,date,id);
						addList(list, "C相正向有功电能",3,"kWh",czvalue,date,id);
						addList(list, "总正向有功电能",4,"kWh",azvalue+bzvalue+czvalue,date,id);

//						Iterator<String> keys = currentData.keys();
//						while (keys.hasNext()) {
//							String key = keys.next();
//							JSONArray arr = currentData.getJSONArray(key);
//							for (int i = 0; i < arr.length(); i++) {
//								result.put(key + i, arr.getDouble(i));
//							}
//
//						}
//						mongoTemplate.insert(list, "RealTimeData");
						logger.info("ali iot rk value: " + list);
						mongoTemplate.insert(list, "RealTimeData");
						aliIotBefore.data(JSON.toJSONString(list));
						break;
					}
					case "error": {

					}
					case "confirm": {
						String cmdcallback=json.put("deviceType", "rk").toString();
						logger.info("ali iot rk "+cmd+": " + cmdcallback);
						aliIotBefore.cmdCallBack(cmdcallback);
						break;
					}
					case "threshold": {
						String dataThreshold=new JSONObject(data).put("deviceType", "rk").toString();
						logger.info("ali iot  rk"+cmd+": " + dataThreshold);
						aliIotBefore.cmdCallBack(dataThreshold);
						break;
					}
					case "alarm": {
						logger.info("ali iot rk alarm: " + m);
						currentData=json.getJSONObject("data");
						int type = currentData.getJSONArray("type").getInt(0);
						int num = currentData.getJSONArray("num").getInt(0);
						double threshold = currentData.getJSONArray("threshold").getDouble(0);
						double alarmvalue = currentData.getJSONArray("alarmvalue").getDouble(0);
						String relay = currentData.getString("relay");

						JSONObject exception = new JSONObject();
						int alarmType=0;
						String content="";
						if(type==1) {
							content="剩余电流报警,告警值："+alarmvalue+"mA";
							alarmType=63;
						}else if(type==2) {
							content="第"+getCH(num)+"温度报警,告警值："+alarmvalue+"℃";
							alarmType=4+num;
						}else if(type==3) {
							content=getABC(num)+"相电流报警,告警值："+alarmvalue+"A";
							alarmType=11+num;
						}else if(type==4) {
							content=getABC(num)+"相电压报警,告警值："+alarmvalue+"V";
							alarmType=8+num;
						}else if(type==7) {
							content="消防联动报警,告警值："+alarmvalue;
							alarmType=64;
						}

						if(type==1) {
							content="剩余电流报警";
							alarmType=63;
						}

						exception.put("createdAt", new Date());
						exception.put("id", id);
						exception.put("paramsType", alarmType);
						exception.put("errorValue", alarmvalue);
						exception.put("threshold", threshold);
						exception.put("relay", relay);
						exception.put("content", content);
						exception.put("deviceType", "rk");
						aliIotBefore.error(exception.toString());
						break;
					}
				}

			} catch (JSONException e) {
				e.printStackTrace();
				logger.info("receive update:   change json  fail" + m);
			}

			return MessageCallback.Action.CommitSuccess;
		});

	}


	public List<RealTimeData> addList(List<RealTimeData> list,String des, int type, String unit, double value, Date createdAt,String deviceId){
		RealTimeData j = new RealTimeData(des,type,unit,value,createdAt,deviceId,"rk");
		list.add(j);
		return list;
	}

	private static String getABC(int input) {
        String sd = "";
        switch (input) {
        case 1:
            sd = "A";
            break;
        case 2:
            sd = "B";
            break;
        case 3:
            sd = "C";
            break;
        default:
            break;
        }
        return sd;
    }

	private static String getCH(int input) {
        String sd = "";
        switch (input) {
        case 1:
            sd = "一";
            break;
        case 2:
            sd = "二";
            break;
        case 3:
            sd = "三";
            break;
        case 4:
            sd = "四";
            break;
        case 5:
            sd = "五";
            break;
        case 6:
            sd = "六";
            break;
        case 7:
            sd = "七";
            break;
        case 8:
            sd = "八";
            break;
        case 9:
            sd = "九";
            break;
        default:
            break;
        }
        return sd;
    }






}
